package com.google.code.coma.rmi;

import com.google.code.coma.domain.Order;
import com.google.code.coma.domain.Part;
import com.google.code.coma.domain.Type;
import org.mozartspaces.capi3.javanative.operation.NativeEntry;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * This selector selects all parts which which are neccessary to assemble a computer
 *
 * @author Bernhard Nickel, e0925384@student.tuwien.ac.at
 */
public class ComputerPartSelector implements EntrySelector<Part> {
	private Order order;

	public ComputerPartSelector(Order order) {
		this.order = order;
	}

	@Override
	public List<Part> selectEntries(List<Part> allEntries) throws SelectionException {
		if (order == null) {
			Part cpu = null;
			Part mainboard = null;
			Part graphicsCard = null;

			List<Part> computerParts = new ArrayList<Part>();

			if (allEntries.size() > 2) {

				for (Part part : allEntries) {

					if (part.getType().equals(Type.CPU)) {
						if (cpu == null) {
							cpu = part;
						}
					} else if (part.getType().equals(Type.Mainboard)) {
						if (mainboard == null) {
							mainboard = part;
						}
					} else if (part.getType().equals(Type.RAM)) {
						if (computerParts.size() < 4) {
							computerParts.add(part);
						}
					} else if (part.getType().equals(Type.GraphicsCard)) {
						if (graphicsCard == null) {
							graphicsCard = part;
						}
					}

					//Ready, no need for further possible parts
					if (cpu != null && mainboard != null && graphicsCard != null && computerParts.size() == 4) {
						computerParts.add(cpu);
						computerParts.add(mainboard);
						computerParts.add(graphicsCard);
						return computerParts;
					}
				}

				//check found parts
				if (cpu != null && mainboard != null & computerParts.size() > 0) {
					if (computerParts.size() == 3) {
						computerParts.remove(2);
					}

					computerParts.add(cpu);
					computerParts.add(mainboard);

					if (graphicsCard != null) {
						computerParts.add(graphicsCard);
					}

					return computerParts;
				}
			}
			throw new SelectionException();
		} else {
			if (order.isFinished()) throw new SelectionException();
			Part cpu = null;
			Part mainboard = null;
			Part graphics = null;
			List<Part> rams = new ArrayList<Part>();
			for (Part p : allEntries) {
				if (cpu == null && p.getType() == Type.CPU && p.getAppellation().equals(order.getCpuType())) {
					cpu = p;
				} else if (rams.size() < order.getNumberOfRAMModules() && p.getType() == Type.RAM) {
					rams.add(p);
				} else if (order.isGraphicsCard() && graphics == null) {
					graphics = p;
				} else if (mainboard == null && p.getType() == Type.Mainboard) {
					mainboard = p;
				}
			}
			if (cpu == null || mainboard == null || rams.size() != order.getNumberOfRAMModules() || (order.isGraphicsCard() && graphics == null))
				throw new SelectionException();
			List<Part> resultList = new ArrayList<Part>();
			resultList.add(cpu);
			resultList.add(mainboard);
			resultList.addAll(rams);
			if (order.isGraphicsCard())
				resultList.add(graphics);
			return resultList;
		}
	}
}
